﻿//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text.RegularExpressions;
//using System.Threading;

//// 表示元素的类
//class Element
//{
//    public int Id { get; set; }
//    public int? ParentId { get; set; }
//    public string Name { get; set; }
//    public string Type { get; set; }
//    public string Comment { get; set; }
//    public List<Element> Children { get; set; } = new List<Element>();

//    public override string ToString()
//    {
//        return $"Id: {Id}, ParentId: {ParentId}, Name: {Name}, Type: {Type}, Comment: {Comment}";
//    }
//}

//// 解析器类
//class S7CodeParser
//{
//    private int currentId = 1;

//    public List<Element> Parse(string code)
//    {
//        var elements = new List<Element>();
//        var lines = code.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
//        var stack = new Stack<Element>();

//        foreach (var line in lines.Select(l => l.Trim()))
//        {
//            if (line.StartsWith("TYPE"))
//            {
//                // 处理 TYPE 部分，去掉可能的分号
//                var cleanLine = line.Replace(";", "").Trim();
//                var typeName = Regex.Match(cleanLine, @"TYPE ""([^""]+)""").Groups[1].Value;
//                var newElement = new Element { Id = Interlocked.Increment(ref currentId) - 1, Name = typeName, Type = "TYPE" };
//                elements.Add(newElement);
//                stack.Push(newElement);
//            }
//            else if (line.StartsWith("DATA_BLOCK"))
//            {
//                var dataBlockName = Regex.Match(line, @"DATA_BLOCK ""([^""]+)""").Groups[1].Value;
//                var newElement = new Element { Id = Interlocked.Increment(ref currentId) - 1, Name = dataBlockName, Type = "DATA_BLOCK" };
//                elements.Add(newElement);
//                stack.Push(newElement);
//            }
//            else if (line.Contains(": Struct"))
//            {
//                var parts = line.Split(new[] { ':' }, 2);
//                var name = parts[0].Trim();
//                var commentMatch = Regex.Match(parts[1], @"//(.*)");
//                var comment = commentMatch.Success ? commentMatch.Groups[1].Value.Trim() : "";

//                var structElement = new Element { Id = Interlocked.Increment(ref currentId) - 1, Name = name, Type = "STRUCT", Comment = comment };
//                if (stack.Count > 0)
//                {
//                    structElement.ParentId = stack.Peek().Id;
//                    stack.Peek().Children.Add(structElement);
//                }
//                stack.Push(structElement);
//            }
//            else if (line.StartsWith("STRUCT"))
//            {
//                if (stack.Count > 0)
//                {
//                    var structElement = new Element { Id = Interlocked.Increment(ref currentId) - 1, Name = "AnonymousStruct", Type = "STRUCT" };
//                    structElement.ParentId = stack.Peek().Id;
//                    stack.Peek().Children.Add(structElement);
//                    stack.Push(structElement);
//                }
//            }
//            else if (line.StartsWith("END_STRUCT"))
//            {
//                if (stack.Count > 0)
//                {
//                    stack.Pop();
//                }
//            }
//            else if (line.Contains(":") && stack.Count > 0)
//            {
//                var parts = line.Split(new[] { ':' }, 2);
//                var name = parts[0].Trim();
//                var typeAndComment = parts[1].Trim();
//                var commentMatch = Regex.Match(typeAndComment, @"//(.*)");
//                var comment = commentMatch.Success ? commentMatch.Groups[1].Value.Trim() : "";
//                var type = commentMatch.Success
//                   ? typeAndComment.Substring(0, typeAndComment.IndexOf("//")).Trim().Replace(";", "")
//                    : typeAndComment.Replace(";", "").Trim();

//                var newElement = new Element { Id = Interlocked.Increment(ref currentId) - 1, Name = name, Type = type, Comment = comment };
//                newElement.ParentId = stack.Peek().Id;
//                stack.Peek().Children.Add(newElement);
//            }
//        }

//        return elements;
//    }

//    public void ExpandCustomTypes(List<Element> elements)
//    {
//        var typeElements = elements.Where(e => e.Type == "TYPE").ToDictionary(e => $"\"{e.Name}\"", e => e);
//        int localCurrentId = currentId;

//        void RecursiveExpand(Element parent)
//        {
//            foreach (var child in parent.Children.ToList())
//            {
              
//                if (typeElements.ContainsKey(child.Type))
//                {
//                    var customType = typeElements[child.Type];
//                    foreach (var subChild in customType.Children)
//                    {
//                        var newChild = new Element
//                        {
//                            Id = Interlocked.Increment(ref localCurrentId) - 1,
//                            ParentId = child.Id,
//                            Name = subChild.Name,
//                            Type = subChild.Type,
//                            Comment = subChild.Comment
//                        };
//                        child.Children.Add(newChild);
//                    }
//                }
//                RecursiveExpand(child);
//            }
//        }

//        foreach (var element in elements)
//        {
//            RecursiveExpand(element);
//        }
//        currentId = localCurrentId;
//    }
//}

//class Program
//{
//    static void Main()
//    {
//        string code = @"
//TYPE ""UDT_01""
//VERSION : 0.1
//   STRUCT
//      Element_1 : Int;
//      Element_2 : Int;
//      Element_3 : String[48];
//   END_STRUCT;

//END_TYPE

//TYPE ""UDT_02""
//VERSION : 0.1
//   STRUCT
//      Element_1 : Int;
//      Element_2 : Int;
//      Element_3 : String[48];
//      Element_4 : Struct   // 注释
//         Element_1 : Int;   // 助手
//         Element_2 : Real;
//      END_STRUCT;
//   END_STRUCT;

//END_TYPE

//DATA_BLOCK ""上位机读取""
//{ S7_Optimized_Access := 'FALSE' }
//VERSION : 0.1
//NON_RETAIN
//   STRUCT 
//      ""PLC Status"" : Int;
//      ""Work pattern"" : Int;
//      Static_1 : Bool;
//      Static_2 : Bool;
//      ""Alarm code"" : Int;
//      ""Station request"" : Int;
//      ""WatchDogToPC  心跳"" : Int;
//      Upload_Start : Int;
//      ""Upload Download  Request"" : Int;
//      Spare : Array[0..43] of Int;
//      ""Subbar code1上传"" : Int;
//      ""Subbar code2上传"" : Int;
//      ""Subbar code3上传"" : Int;
//      ""Subbar code4上传"" : Int;
//      ""Subbar code5上传"" : Int;
//      Spare_2 : Array[0..50] of Int;
//      Station_N0 : String[10];
//      Pallet_N0 : String[10];
//      ""Batch number"" : String[40];
//      BarcodeInAgv : String[40];
//      ""Subbar code_1"" : String[40];
//      ""Subbar code_2"" : String[40];
//      ""Subbar code_3"" : String[40];
//      ""Subbar code_4"" : String[40];
//      ""Subbar code_5"" : String[40];
//      Spare_1 : Array[0..233] of Int;
//      Static_7 : Struct
//         Result : Int;
//         PartType : Real;
//         SerialNumber : Real;
//         PressPosition : Int;
//      END_STRUCT;
//      Result : Int;
//      PartType : String[10];
//      SerialNumber : Int;   // 注释
//      PressPosition : Real;   // 注释
//      PressForce : Real;
//      Cycle_time : Real;
//      Static_3 { S7_SetPoint := 'False'} : ""UDT_01"";
//      Static_4 : Int;
//      Static_5 : ""UDT_02"";   // 注释
//      Static_6 : Int;
//   END_STRUCT;

//BEGIN

//END_DATA_BLOCK";

//        var parser = new S7CodeParser();
//        var elements = parser.Parse(code);
//        parser.ExpandCustomTypes(elements);

//        foreach (var element in elements)
//        {
//            Console.WriteLine(element);
//            PrintChildren(element.Children, 1);
//        }
//    }

//    static void PrintChildren(List<Element> children, int indentLevel)
//    {
//        var indent = new string(' ', indentLevel * 2);
//        foreach (var child in children)
//        {
//            Console.WriteLine($"{indent}{child}");
//            PrintChildren(child.Children, indentLevel + 1);
//        }
//    }
//}